﻿using Autodesk.Revit.UI;
using log4net;
using Newtonsoft.Json;
using Rvt2ifcTool.Common;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Rvt2ifcTool
{

	public partial class WaittingForm : Form
	{
		public static ILog log { get { return LogManager.GetLogger(typeof(WaittingForm)); } }
		public WaittingForm()
		{
			InitializeComponent();
		}
		Thread waitConvertThread = null;
		Thread waitCombinThread = null;
		private XeoConfigInfo gXeoConfigInfo = new XeoConfigInfo();
		private void WaittingForm_Load(object sender, EventArgs e)
		{
			initXeoConfigInfo();
			waitConvertThread = new Thread(ConvertLoop);
			waitConvertThread.Start();
			Thread.Sleep(1000);
			waitCombinThread = new Thread(CombinLoop);
			waitCombinThread.Start();
			AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;
		}

		private void initXeoConfigInfo()
		{
			if (File.Exists(configFilePath))
			{
				try
				{
					string json = File.ReadAllText(configFilePath);
					gXeoConfigInfo = JsonConvert.DeserializeObject<XeoConfigInfo>(json);
					textBox3.Text = gXeoConfigInfo.ProcessBatPath;
					textBox2.Text = gXeoConfigInfo.BaseDirectory;
				}
				catch (Exception)
				{
					gXeoConfigInfo.ProcessBatPath = textBox3.Text;
					gXeoConfigInfo.BaseDirectory = textBox2.Text;
				}
			}
			else
			{
				gXeoConfigInfo.ProcessBatPath = textBox3.Text;
				gXeoConfigInfo.BaseDirectory = textBox2.Text;
			}
		}

		private static Assembly OnAssemblyResolve(object sender, ResolveEventArgs args)
		{
			// 在安装路径中查找相关dll并加载 
			var assemblyName = new AssemblyName(args.Name);
			var file = string.Format("{0}.dll", Path.Combine("D:\\xeokit\\rvt2ifc\\Rvt2ifcTool\\bin\\Debug", assemblyName.Name));
			if (File.Exists(file))
			{
				return Assembly.LoadFile(file);
			}
			return args.RequestingAssembly;
		}
		private bool isWaiting = false;
		private async void CombinLoop()
		{
			// 进入循环等待状态
			isWaiting = true;

			while (isWaiting)
			{
				// 处理消息队列以保持界面响应
				Application.DoEvents();
				PrintWithTimestamp("查询是否有待合并数据！");
				List<Project> projects = RestUtils.GetWaitCombinList();
				if (projects == null || projects.Count == 0) { continue; }

				foreach (var project in projects)
				{
					//组装文件夹路径

					string projectDirectory = XeokitUtils.GetProjectDirectory(gXeoConfigInfo.BaseDirectory, project.uuid);
					for (int i = 0; i < project.modelUuids.Count; i++)
					{
						string modelUuid = project.modelUuids[i];
						string lonelyProjectUuid = project.lonelyProjectUuids[i];



						string modelDirectory = XeokitUtils.GetModelDirectory(projectDirectory, modelUuid);

						string lonelyProjectDirectory = XeokitUtils.GetProjectDirectory(gXeoConfigInfo.BaseDirectory, lonelyProjectUuid);
						string lonelyModelDirectory = XeokitUtils.GetModelDirectory(lonelyProjectDirectory, modelUuid);

						XeokitUtils.CopyDirectory(lonelyModelDirectory, modelDirectory);
					}
					//创建index.json文件
					string json = XeokitUtils.CreateIndexJsonFile(XeokitUtils.GetProjectJsonPath(projectDirectory), project.uuid, project.projectName, project.modelUuids, project.modelNames);
					RestUtils.UpdateProjectState(project.uuid, 1);
					PrintWithTimestamp(json);
				}
				Thread.Sleep(2000);
			}

			// 退出循环后执行清理操作，如果有的话
			// 例如，更新界面、关闭资源等
		}
		private async void ConvertLoop()
		{
			// 进入循环等待状态
			isWaiting = true;

			while (isWaiting)
			{
				// 处理消息队列以保持界面响应
				Application.DoEvents();
				PrintWithTimestamp("查询是否有待转换数据！");
				List<UploadedFile> files = RestUtils.GetWaitList();
				if (files == null || files.Count == 0) { continue; }

				if (files.Count > 0)
				{
					files[0].filePath = Path.Combine(gXeoConfigInfo.BaseDirectory, files[0].storedName);
					string ext = Path.GetExtension(files[0].storedName);
					PrintWithTimestamp("扫描到文件：" + files[0].filePath);
					UploadedFile uploadedFile = files[0];
					PrintWithTimestamp("开始下载");
					if (!File.Exists(uploadedFile.filePath))
					{
						uploadedFile.filePath = await RestUtils.DownLoadFile(gXeoConfigInfo.BaseDirectory, uploadedFile.storedName);
					}
					if (!File.Exists(uploadedFile.filePath))
					{
						PrintWithTimestamp("下载失败！");
						continue;
					}
					if (ext == ".rvt")
					{
						if (!Globle.gExEvent.IsPending)
						{
							//Globle.gMyHandler = new RevitHandler(); //外部事件声明
							//Globle.gExEvent = ExternalEvent.Create(Globle.gMyHandler);
							try
							{

								Globle.gMyHandler.mProjectUuid = uploadedFile.projectUuid;
								Globle.gMyHandler.mModelUuid = uploadedFile.modelUuid;
								Globle.gMyHandler.mModelName = uploadedFile.pinyinName;
								Globle.gMyHandler.mOutputGuid = Guid.NewGuid().ToString("N").ToLower();
								Globle.gMyHandler.gRvtPath = files[0].filePath;
								Globle.gMyHandler.gBaseDirectory = gXeoConfigInfo.BaseDirectory;
								Globle.gMyHandler.gScriptName = gXeoConfigInfo.ProcessBatPath;
								Globle.gExEvent.Raise();
								RestUtils.UpdateXktState(uploadedFile.uuid, 1);
								PrintWithTimestamp("转换完成！");
							}
							catch (Exception ex)
							{
								PrintWithTimestamp(ex.ToString());
								log.Error(ex);
							}
						}
						else
						{
							PrintWithTimestamp("Revit忙！");
						}
					}
					else if (ext == ".ifc")
					{
						string projectDirectory = XeokitUtils.GetProjectDirectory(gXeoConfigInfo.BaseDirectory, uploadedFile.projectUuid);
						string fileName = Path.GetFileNameWithoutExtension(uploadedFile.fileName);
						XeokitUtils.ExportXkt(files[0].filePath,
											projectDirectory,
											gXeoConfigInfo.ProcessBatPath,
											 Guid.NewGuid().ToString("N").ToLower(),
											 uploadedFile.modelUuid,
											 fileName,
											 uploadedFile.projectUuid);
						RestUtils.UpdateXktState(uploadedFile.uuid, 1);
						PrintWithTimestamp("转换完成！");
					}

				}
				// 在实际应用中，你可能需要添加其他的等待逻辑，例如等待某个条件满足
				// 这里简单地等待一段时间
				Thread.Sleep(2000);
			}

			// 退出循环后执行清理操作，如果有的话
			// 例如，更新界面、关闭资源等
		}
		// 在你的控件所在的线程中执行更新
		// 打印时加上时间，并换行
		private void PrintWithTimestamp(string text)
		{
			try
			{
				log.Info(text);
				string timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");  // 获取当前时间
				string fullText = $"[{timestamp}] {text}";  // 拼接时间和文本
															//textBox1.Invoke(new Action<string>(PrintWithTimestamp), text);
															// 检查是否需要跨线程调用
				if (textBox1.InvokeRequired)
				{
					textBox1.Invoke(new Action<string>(PrintWithTimestamp), text);
				}
				else
				{
					// 每次打印时加上时间，并换行
					textBox1.AppendText(fullText + Environment.NewLine);
				}
			}
			catch (Exception ex)
			{
				log.Error(ex);
			}

		}
		string configFilePath = "XeokitConfig.json";
		private void WaittingForm_FormClosing(object sender, FormClosingEventArgs e)
		{

			saveConfigInfo();
			e.Cancel = true;
			//if (waitConvertThread != null)
			//{
			//	waitConvertThread.Abort();
			//}
			//if (waitCombinThread != null)
			//{
			//	waitCombinThread.Abort();
			//}
		}
		private void saveConfigInfo()
		{
			XeoConfigInfo xeoConfigInfo = new XeoConfigInfo();
			xeoConfigInfo.ProcessBatPath = textBox3.Text;
			xeoConfigInfo.BaseDirectory = textBox2.Text;
			File.WriteAllText(configFilePath, JsonConvert.SerializeObject(xeoConfigInfo));
		}

		private void textBox3_TextChanged(object sender, EventArgs e)
		{

			gXeoConfigInfo.ProcessBatPath = textBox3.Text.Trim();
		}

		private void textBox2_TextChanged(object sender, EventArgs e)
		{
			gXeoConfigInfo.BaseDirectory = textBox2.Text.Trim();
		}
	}
}

